using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Practices.ObjectBuilder;
using NUnit.Framework;
using Rhino.Mocks;
using SCSFContrib.CompositeUI.WPF.Activation;
using SCSFContrib.CompositeUI.WPF.BuilderStrategies;

namespace SCSFContrib.CompositeUI.WPF.UnitTest.BuilderStrategies
{
	[TestFixture]
	public sealed class WindowsServiceStrategyTest : UnitTest
	{
		private WindowsServiceStrategy _windowsServiceStrategy;
		private TestableRootWorkItem _workItem;

		protected override void SetUpCore()
		{
			base.SetUpCore();
			_windowsServiceStrategy = new WindowsServiceStrategy();
			_workItem = new TestableRootWorkItem();
		}

		[Test]
		public void BuildUp_ShouldIgnoreAnyNonWorkItemArguments()
		{
			IBuilderContext context = Mocks.DynamicMock<IBuilderContext>();
			Mocks.ReplayAll();

			_windowsServiceStrategy.BuildUp(context, null, "abc", null);
			_windowsServiceStrategy.BuildUp(context, null, 123, null);
			_windowsServiceStrategy.BuildUp(context, null, this, null);
			_windowsServiceStrategy.BuildUp(context, null, _windowsServiceStrategy, null);
		}

		[Test]
		public void BuildUp_ShouldAddRequisiteServicesIfTheyDontYetExistInWorkItem()
		{
			IBuilderContext context = Mocks.DynamicMock<IBuilderContext>();
			Mocks.ReplayAll();

			Assert.IsFalse(_workItem.Services.Contains<IFrameworkElementActivationService>());
			_windowsServiceStrategy.BuildUp(context, null, _workItem, null);
			Assert.IsTrue(_workItem.Services.Contains<IFrameworkElementActivationService>());
		}

		[Test]
		public void BuildUp_ShouldAddRequisiteServicesEvenIfTheyExistInParentContainer()
		{
			IBuilderContext context = Mocks.DynamicMock<IBuilderContext>();
			Mocks.ReplayAll();

			TestableRootWorkItem childWorkItem = new TestableRootWorkItem(_workItem);

			//add service to root work item
			_windowsServiceStrategy.BuildUp(context, null, _workItem, null);
			Assert.IsTrue(_workItem.Services.ContainsLocal(typeof(IFrameworkElementActivationService)));
			Assert.IsTrue(childWorkItem.Services.Contains(typeof(IFrameworkElementActivationService)));
			Assert.IsFalse(childWorkItem.Services.ContainsLocal(typeof(IFrameworkElementActivationService)));
			//build up child work item
			_windowsServiceStrategy.BuildUp(context, null, childWorkItem, null);
			//and make sure service was added, even though it was present in the parent
			Assert.IsTrue(childWorkItem.Services.ContainsLocal(typeof(IFrameworkElementActivationService)));
		}

		[Test]
		public void BuildUp_ShouldDoNothingIfRequisiteServicesAlreadyExist()
		{
			IBuilderContext context = Mocks.DynamicMock<IBuilderContext>();
			IFrameworkElementActivationService frameworkElementActivationService = Mocks.DynamicMock<IFrameworkElementActivationService>();
			Mocks.ReplayAll();

			Assert.IsFalse(_workItem.Services.Contains<IFrameworkElementActivationService>());
			_workItem.Services.Add(typeof(IFrameworkElementActivationService), frameworkElementActivationService);
			Assert.IsTrue(_workItem.Services.Contains<IFrameworkElementActivationService>());
			_windowsServiceStrategy.BuildUp(context, null, _workItem, null);
			Assert.IsTrue(_workItem.Services.Contains<IFrameworkElementActivationService>());
			Assert.AreSame(frameworkElementActivationService, _workItem.Services.Get<IFrameworkElementActivationService>());
		}
	}
}
